
#ifndef  __PTR_LINKED_LIST__H
#define  __PTR_LINKED_LIST__H

struct _PtrLinkedListCell;
typedef struct _PtrLinkedListCell* PtrLinkedListCellPtr;

typedef struct _PtrLinkedList
{
    int size;
    PtrLinkedListCellPtr head;
	PtrLinkedListCellPtr tail;
}  PtrLinkedList;

PtrLinkedList* PtrLinkedList__alloc();
void PtrLinkedList__init(PtrLinkedList* list);
void PtrLinkedList__free(PtrLinkedList* list);
void PtrLinkedList__clear(PtrLinkedList* list);

void PtrLinkedList__insert_head(PtrLinkedList* list, void* data);
void PtrLinkedList__insert_tail(PtrLinkedList* list, void* data);
int  PtrLinkedList__delete(PtrLinkedList* list, void* data);
void* PtrLinkedList__pop_head(PtrLinkedList* list);
int PtrLinkedList__HasItems(const PtrLinkedList* list);
int PtrLinkedList__Count(const PtrLinkedList* list);

/* If we really want to work in an abstract way, we should use iterators */
typedef  const struct _PtrLinkedListCell* PtrLinkedListIterator;

void  PtrLinkedList__iterator_init(PtrLinkedListIterator* iter, PtrLinkedList* lst);
void  PtrLinkedList__iterator_next(PtrLinkedListIterator* iter);
int   PtrLinkedList__iterator_is_done(const PtrLinkedListIterator iter);
void* PtrLinkedList__iterator_get_data(const PtrLinkedListIterator iter);

#endif  /* __PTR_LINKED_LIST__H */

